package com.brooks.demo.program.p1;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 面试题
 * 实现一个容器，提供两个方法，add,size
 * 写两个线程，线程1往容器里添加10个元素，线程2实现监控元素的个数，当个数到5时，线程2给出提示并结束
 *
 * 这里利用countDownLatch的特性，t2 先执行，然后await。t1每次添加元素的时候countDown一次，5次的
 * 时候t2就开始执行了，t1再await,然后等t2执行结束，t2 countDown,t1 继续执行直到结束
 * @Author mihutu
 * @Date 2020/10/20 11:11
 * @Version 1.0
 */
public class DemoCountDownlatch {
    /**
     * 这里使用同步容器来保证数据一致,否则会出现脏读的情况
     */
    volatile List list = Collections.synchronizedList(new LinkedList<>());

    public void add(Object o) {
        list.add(o);
    }

    public int size() {
        return list.size();
    }

    public static void main(String[] args) {
        DemoCountDownlatch v = new DemoCountDownlatch();
        CountDownLatch latch = new CountDownLatch(5);
        CountDownLatch latch1 = new CountDownLatch(1);
        //监控数量的线程
        new Thread(() -> {
            System.out.println("t2监控已启动");
            if (v.size() != 5) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("已经到第5个了，我结束了");
            latch1.countDown();
        }, "t2").start();
        //添加元素的线程
        new Thread(() -> {
            System.out.println("t1已启动，准备添加元素");
            for (int i = 0; i < 10; i++) {
                v.add(new Object());
                System.out.println("添加了第" + i + "个元素");
                latch.countDown();
                if(v.size()==5){
                    try {
                        latch1.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("t1 结束");
        }, "t1").start();
    }
}
